home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / UPDATE- Int&Libs 3.2 / PInterfaces / Multiprocessing.p < prev    next >
Encoding:
Text File  |  1999-05-25  |  23.2 KB  |  648 lines  |  [TEXT/MPS ]

  1. {
  2.      File:        Multiprocessing.p
  3.  
  4.      Contains:    Multiprocessing interfaces
  5.  
  6.      Version:    Technology:    Multiprocessing API version 2.0, integrated nanokernel support
  7.                  Release:    Veronica Seed, Use with 3.2 Universal Interfaces
  8.  
  9.      Copyright:    © 1996-1999 by Apple Computer, Inc. and © 1995-1997 DayStar Digital, Inc.
  10.  
  11.      Bugs?:        For bug reports, consult the following page on
  12.                  the World Wide Web:
  13.  
  14.                      http://developer.apple.com/bugreporter/
  15.  
  16. }
  17. {
  18.    ===========================================================================================
  19.    *** WARNING: You must properly check the availability of MP services before calling them!
  20.    See the section titled "Checking API Availability".
  21.    ===========================================================================================
  22. }
  23.  
  24.  
  25. {$IFC UNDEFINED UsingIncludes}
  26. {$SETC UsingIncludes := 0}
  27. {$ENDC}
  28.  
  29. {$IFC NOT UsingIncludes}
  30.  UNIT Multiprocessing;
  31.  INTERFACE
  32. {$ENDC}
  33.  
  34. {$IFC UNDEFINED __MULTIPROCESSING__}
  35. {$SETC __MULTIPROCESSING__ := 1}
  36.  
  37. {$I+}
  38. {$SETC MultiprocessingIncludes := UsingIncludes}
  39. {$SETC UsingIncludes := 1}
  40.  
  41. {$IFC UNDEFINED __MACTYPES__}
  42. {$I MacTypes.p}
  43. {$ENDC}
  44. {$IFC UNDEFINED __CODEFRAGMENTS__}
  45. {$I CodeFragments.p}
  46. {$ENDC}
  47.  
  48. {$IFC UNDEFINED __DRIVERSERVICES__}
  49. {$I DriverServices.p}
  50. {$ENDC}
  51.  
  52.  
  53.  
  54. {$PUSH}
  55. {$ALIGN POWER}
  56. {$LibExport+}
  57.  
  58. {
  59.    ===========================================================================================
  60.    This is the header file for version 2.0 of the Mac OS multiprocessing support.  This version
  61.    has been totally reimplemented and has significant new services.  The main goal of the
  62.    reimplementation has been to transfer task management into the core operating system to provide
  63.    much more reliable and more efficient operation, including on single processor machines.
  64.    The memory management has also been massively improved, it is much faster and wastes much
  65.    less space.  New services include POSIX style per-task storage, timers with millisecond and
  66.    microsecond resolutions, memory allocation at a specified alignment, and system pageable
  67.    and RAM resident memory pools.  See the MP API documentation for details.
  68.    The old "DayStar" debugging services (whose names began with an underscore) have been
  69.    removed from this header.  A very few are still implemented for binary compatibility, or in
  70.    cases where they happened to be exposed inappropriately.  (E.g. _MPIsFullyInitialized must
  71.    be called to see if the MP API is ReallyTruly™ usable.)  New code and recompiles of old
  72.    code should avoid use of these defunct services, except for _MPIsFullyInitialized.
  73.    ===========================================================================================
  74. }
  75.  
  76.  
  77. {
  78.    ===========================================================================================
  79.    The following services are from the original MP API and remain supported in version 2.0:
  80.       MPProcessors
  81.       MPCreateTask
  82.       MPTerminateTask
  83.       MPCurrentTaskID
  84.       MPYield
  85.       MPExit
  86.       MPCreateQueue
  87.       MPDeleteQueue
  88.       MPNotifyQueue
  89.       MPWaitOnQueue
  90.       MPCreateSemaphore
  91.       MPCreateBinarySemaphore        (In C only, a macro that calls MPCreateSemaphore.)
  92.       MPDeleteSemaphore
  93.       MPSignalSemaphore
  94.       MPWaitOnSemaphore
  95.       MPCreateCriticalRegion
  96.       MPDeleteCriticalRegion
  97.       MPEnterCriticalRegion
  98.       MPExitCriticalRegion
  99.       MPAllocate                    (Deprecated, use MPAllocateAligned for new builds.)
  100.       MPFree
  101.       MPBlockCopy
  102.       MPLibraryIsLoaded            (In C only, a macro.)
  103.       _MPIsFullyInitialized        (See comments about checking for MP API availability.)
  104.    ===========================================================================================
  105. }
  106.  
  107.  
  108. {
  109.    ===========================================================================================
  110.    The following services are new in version 2.0:
  111.       MPProcessorsScheduled
  112.       MPSetTaskWeight
  113.       MPTaskIsPreemptive
  114.       MPAllocateTaskStorageIndex
  115.       MPDeallocateTaskStorageIndex
  116.       MPSetTaskStorageValue
  117.       MPGetTaskStorageValue
  118.       MPSetQueueReserve
  119.       MPCreateEvent
  120.       MPDeleteEvent
  121.       MPSetEvent
  122.       MPWaitForEvent
  123.       UpTime
  124.       DurationToAbsolute
  125.       AbsoluteToDuration
  126.       MPDelayUntil
  127.       MPCreateTimer
  128.       MPDeleteTimer
  129.       MPSetTimerNotify
  130.       MPArmTimer
  131.       MPCancelTimer
  132.       MPSetExceptionHandler
  133.       MPThrowException
  134.       MPDisposeTaskException
  135.       MPExtractTaskState
  136.       MPSetTaskState
  137.       MPRegisterDebugger
  138.       MPUnregisterDebugger
  139.       MPAllocateAligned            (Preferred over MPAllocate.)
  140.       MPGetAllocatedBlockSize
  141.       MPBlockClear
  142.       MPDataToCode
  143.       MPRemoteCall                (Preferred over _MPRPC.)
  144.    ===========================================================================================
  145. }
  146.  
  147.  
  148. {
  149.    ===========================================================================================
  150.    The following services are "unofficial" extensions to the original API.  They are not in
  151.    the multiprocessing API documentation, but were in previous versions of this header.  They
  152.    remain supported in version 2.0.  They may not be supported in other environments.
  153.       _MPRPC                        (Deprecated, use MPRemoteCall for new builds.)
  154.       _MPAllocateSys                (Deprecated, use MPAllocateAligned for new builds.)
  155.       _MPTaskIsToolboxSafe
  156.       _MPLibraryVersion
  157.       _MPLibraryIsCompatible
  158.    ===========================================================================================
  159. }
  160.  
  161.  
  162. {
  163.    ===========================================================================================
  164.    The following services were in previous versions of this header for "debugging only" use.
  165.    They are NOT implemented in version 2.0.  For old builds they can be accessed by defining
  166.    the symbol MPIncludeDefunctServices to have a nonzero value.
  167.       _MPInitializePrintf
  168.       _MPPrintf
  169.       _MPDebugStr
  170.       _MPStatusPString
  171.       _MPStatusCString
  172.    ===========================================================================================
  173. }
  174.  
  175.  
  176. {
  177.    §
  178.    ===========================================================================================
  179.    General Types and Constants
  180.    ===========================
  181. }
  182.  
  183.  
  184.  
  185.  
  186. CONST
  187.     MPLibrary_MajorVersion        = 2;
  188.     MPLibrary_MinorVersion        = 0;
  189.     MPLibrary_Release            = 1;
  190.     MPLibrary_DevelopmentRevision = 1;
  191.  
  192.  
  193.  
  194. TYPE
  195.     MPProcessID                            = CFragContextID;
  196.     MPTaskID = ^LONGINT;
  197.     MPQueueID = ^LONGINT;
  198.     MPSemaphoreID = ^LONGINT;
  199.     MPCriticalRegionID = ^LONGINT;
  200.     MPTimerID = ^LONGINT;
  201.     MPEventID = ^LONGINT;
  202.     MPAddressSpaceID = ^LONGINT;
  203.     MPOpaqueID = ^LONGINT;
  204.  
  205. CONST
  206.     kMPNoID                        = 0;                            {  New code should use kInvalidID everywhere. }
  207.  
  208.  
  209.  
  210. TYPE
  211.     MPTaskOptions                        = OptionBits;
  212.     TaskStorageIndex                    = UInt32;
  213.     TaskStorageValue                    = UInt32;
  214.     MPSemaphoreCount                    = ItemCount;
  215.     MPTaskWeight                        = UInt32;
  216.     MPEventFlags                        = UInt32;
  217.     MPExceptionKind                        = UInt32;
  218.     MPTaskStateKind                        = UInt32;
  219.     MPDebuggerLevel                        = UInt32;
  220.  
  221. CONST
  222.     kDurationImmediate            = 0;
  223.     kDurationForever            = $7FFFFFFF;
  224.     kDurationMillisecond        = 1;
  225.     kDurationMicrosecond        = -1;
  226.  
  227.  
  228. {
  229.    §
  230.    ===========================================================================================
  231.    Tasking Services
  232.    ================
  233. }
  234.  
  235.  
  236. FUNCTION MPProcessors: ItemCount; C;
  237. {  The physical total. }
  238. FUNCTION MPProcessorsScheduled: ItemCount; C;
  239. {  Those currently in use. }
  240.  
  241. TYPE
  242. {$IFC TYPED_FUNCTION_POINTERS}
  243.     TaskProc = FUNCTION(parameter: UNIV Ptr): OSStatus; C;
  244. {$ELSEC}
  245.     TaskProc = ProcPtr;
  246. {$ENDC}
  247.  
  248. {  ------------------------------------------------------------------------------------------- }
  249.  
  250.  
  251. FUNCTION MPCreateTask(entryPoint: TaskProc; parameter: UNIV Ptr; stackSize: ByteCount; notifyQueue: MPQueueID; terminationParameter1: UNIV Ptr; terminationParameter2: UNIV Ptr; options: MPTaskOptions; VAR task: MPTaskID): OSStatus; C;
  252. FUNCTION MPTerminateTask(task: MPTaskID; terminationStatus: OSStatus): OSStatus; C;
  253. FUNCTION MPSetTaskWeight(task: MPTaskID; weight: MPTaskWeight): OSStatus; C;
  254. FUNCTION MPTaskIsPreemptive(taskID: MPTaskID): BOOLEAN; C;
  255. {  May be kInvalidID. }
  256. PROCEDURE MPExit(status: OSStatus); C;
  257. PROCEDURE MPYield; C;
  258. FUNCTION MPCurrentTaskID: MPTaskID; C;
  259.  
  260. {  ------------------------------------------------------------------------------------------- }
  261.  
  262.  
  263. {
  264.    ---------------------------------------------------
  265.    ! The task storage services are new in version 2.0.
  266. }
  267.  
  268.  
  269. FUNCTION MPAllocateTaskStorageIndex(VAR index: TaskStorageIndex): OSStatus; C;
  270. FUNCTION MPDeallocateTaskStorageIndex(index: TaskStorageIndex): OSStatus; C;
  271. FUNCTION MPSetTaskStorageValue(index: TaskStorageIndex; value: TaskStorageValue): OSStatus; C;
  272. FUNCTION MPGetTaskStorageValue(index: TaskStorageIndex): TaskStorageValue; C;
  273.  
  274. {
  275.    §
  276.    ===========================================================================================
  277.    Synchronization Services
  278.    ========================
  279. }
  280.  
  281.  
  282. FUNCTION MPCreateQueue(VAR queue: MPQueueID): OSStatus; C;
  283. FUNCTION MPDeleteQueue(queue: MPQueueID): OSStatus; C;
  284. FUNCTION MPNotifyQueue(queue: MPQueueID; param1: UNIV Ptr; param2: UNIV Ptr; param3: UNIV Ptr): OSStatus; C;
  285. FUNCTION MPWaitOnQueue(queue: MPQueueID; VAR param1: UNIV Ptr; VAR param2: UNIV Ptr; VAR param3: UNIV Ptr; timeout: Duration): OSStatus; C;
  286. FUNCTION MPSetQueueReserve(queue: MPQueueID; count: ItemCount): OSStatus; C;
  287.  
  288. {  ------------------------------------------------------------------------------------------- }
  289.  
  290.  
  291. FUNCTION MPCreateSemaphore(maximumValue: MPSemaphoreCount; initialValue: MPSemaphoreCount; VAR semaphore: MPSemaphoreID): OSStatus; C;
  292. FUNCTION MPDeleteSemaphore(semaphore: MPSemaphoreID): OSStatus; C;
  293. FUNCTION MPSignalSemaphore(semaphore: MPSemaphoreID): OSStatus; C;
  294. FUNCTION MPWaitOnSemaphore(semaphore: MPSemaphoreID; timeout: Duration): OSStatus; C;
  295.  
  296.  
  297. {  ------------------------------------------------------------------------------------------- }
  298.  
  299.  
  300. FUNCTION MPCreateCriticalRegion(VAR criticalRegion: MPCriticalRegionID): OSStatus; C;
  301. FUNCTION MPDeleteCriticalRegion(criticalRegion: MPCriticalRegionID): OSStatus; C;
  302. FUNCTION MPEnterCriticalRegion(criticalRegion: MPCriticalRegionID; timeout: Duration): OSStatus; C;
  303. FUNCTION MPExitCriticalRegion(criticalRegion: MPCriticalRegionID): OSStatus; C;
  304.  
  305. {  ------------------------------------------------------------------------------------------- }
  306.  
  307.  
  308. FUNCTION MPCreateEvent(VAR event: MPEventID): OSStatus; C;
  309. FUNCTION MPDeleteEvent(event: MPEventID): OSStatus; C;
  310. FUNCTION MPSetEvent(event: MPEventID; flags: MPEventFlags): OSStatus; C;
  311. FUNCTION MPWaitForEvent(event: MPEventID; VAR flags: MPEventFlags; timeout: Duration): OSStatus; C;
  312.  
  313. {
  314.    §
  315.    ===========================================================================================
  316.    Timer Services
  317.    ==============
  318. }
  319.  
  320.  
  321. {
  322.    --------------------------------------------
  323.    ! The timer services are new in version 2.0.
  324. }
  325.  
  326.  
  327. {$IFC 0 }
  328. {  For now these are taken from DriverServices, should be in a better place. }
  329. FUNCTION UpTime: AbsoluteTime; C;
  330. FUNCTION DurationToAbsolute(duration: Duration): AbsoluteTime; C;
  331. FUNCTION AbsoluteToDuration(time: AbsoluteTime): Duration; C;
  332. {$ENDC}  {0}
  333.  
  334.  
  335. CONST
  336.                                                                 {  For MPArmTimer options }
  337.     kMPPreserveTimerIDMask        = $00000001;
  338.     kMPTimeIsDeltaMask            = $00000002;
  339.     kMPTimeIsDurationMask        = $00000004;
  340.  
  341.  
  342. FUNCTION MPDelayUntil(VAR expirationTime: AbsoluteTime): OSStatus; C;
  343. FUNCTION MPCreateTimer(VAR timerID: MPTimerID): OSStatus; C;
  344. FUNCTION MPDeleteTimer(timerID: MPTimerID): OSStatus; C;
  345. FUNCTION MPSetTimerNotify(timerID: MPTimerID; notificationID: MPOpaqueID; notifyParam1: UNIV Ptr; notifyParam2: UNIV Ptr; notifyParam3: UNIV Ptr): OSStatus; C;
  346. FUNCTION MPArmTimer(timerID: MPTimerID; VAR expirationTime: AbsoluteTime; options: OptionBits): OSStatus; C;
  347. FUNCTION MPCancelTimer(timerID: MPTimerID; VAR timeRemaining: AbsoluteTime): OSStatus; C;
  348.  
  349. {
  350.    §
  351.    ===========================================================================================
  352.    Memory Services
  353.    ===============
  354. }
  355.  
  356.  
  357.  
  358. CONST
  359.                                                                 {  Maximum allocation request size is 1GB. }
  360.     kMPMaxAllocSize                = 1073741824;
  361.  
  362.                                                                 {  Values for the alignment parameter to MPAllocateAligned. }
  363.     kMPAllocateDefaultAligned    = 0;
  364.     kMPAllocate8ByteAligned        = 3;
  365.     kMPAllocate16ByteAligned    = 4;
  366.     kMPAllocate32ByteAligned    = 5;
  367.     kMPAllocate1024ByteAligned    = 10;
  368.     kMPAllocate4096ByteAligned    = 12;
  369.     kMPAllocateMaxAlignment        = 16;                            {  Somewhat arbitrary limit on expectations. }
  370.     kMPAllocateAltiVecAligned    = 4;                            {  The P.C. name. }
  371.     kMPAllocateVMXAligned        = 4;                            {  The older, common name. }
  372.     kMPAllocateVMPageAligned    = 254;                            {  Pseudo value, converted at runtime. }
  373.     kMPAllocateInterlockAligned    = 255;                            {  Pseudo value, converted at runtime. }
  374.  
  375.                                                                 {  Values for the options parameter to MPAllocateAligned. }
  376.     kMPAllocateClearMask        = $0001;                        {  Zero the allocated block. }
  377.     kMPAllocateGloballyMask        = $0002;                        {  Allocate from the globally visible pool. }
  378.     kMPAllocateResidentMask        = $0004;                        {  Allocate from the RAM-resident pool. }
  379.     kMPAllocateNoGrowthMask        = $0010;                        {  Do not attempt to grow the pool. }
  380.  
  381.  
  382. {  ------------------------------------------------------------------------------------------- }
  383.  
  384.  
  385. FUNCTION MPAllocateAligned(size: ByteCount; alignment: ByteParameter; options: OptionBits): LogicalAddress; C;
  386. {  ! MPAllocateAligned is new in version 2.0. }
  387. FUNCTION MPAllocate(size: ByteCount): LogicalAddress; C;
  388. {  Use MPAllocateAligned instead. }
  389. PROCEDURE MPFree(object: LogicalAddress); C;
  390. FUNCTION MPGetAllocatedBlockSize(object: LogicalAddress): ByteCount; C;
  391. {  ------------------------------------------------------------------------------------------- }
  392.  
  393.  
  394. PROCEDURE MPBlockCopy(source: LogicalAddress; destination: LogicalAddress; size: ByteCount); C;
  395. PROCEDURE MPBlockClear(address: LogicalAddress; size: ByteCount); C;
  396. {  ! MPBlockClear is new in version 2.0. }
  397. PROCEDURE MPDataToCode(address: LogicalAddress; size: ByteCount); C;
  398. {  ! MPDataToCode is new in version 2.0. }
  399. {
  400.    §
  401.    ===========================================================================================
  402.    Exception/Debugging Services
  403.    ============================
  404. }
  405.  
  406.  
  407. {
  408.    -------------------------------------------------------------------------------------------
  409.    *** Important Note ***
  410.    ----------------------
  411.    
  412.    The functions MPExtractTaskState and MPSetTaskState infer the size of the "info" buffer
  413.    from the "kind" parameter.  A given value for MPTaskStateKind will always refer to a
  414.    single specific physical buffer layout.  Should new register sets be added, or the size
  415.    or number of any registers change, new values of MPTaskStateKind will be introduced to
  416.    refer to the new buffer layouts.  The types for the buffers are in MachineExceptions.
  417.    
  418.    The correspondence between MPTaskStateKind values and MachineExceptions types is:
  419.    
  420.           kMPTaskStateRegisters                -> RegisterInformation
  421.           kMPTaskStateFPU                        -> FPUInformation
  422.           kMPTaskStateVectors                    -> VectorInformation
  423.           kMPTaskStateMachine                    -> MachineInformation
  424.           kMPTaskState32BitMemoryException    -> ExceptionInfo for old-style 32-bit memory exceptions
  425.    
  426.       For reference, on PowerPC the MachineExceptions types contain:
  427.    
  428.           RegisterInformation    -> The GPRs, 32 values of 64 bits each.
  429.           FPUInformation        -> The FPRs plus FPSCR, 32 values of 64 bits each, one value of
  430.                                   32 bits.
  431.           VectorInformation    -> The AltiVec vector registers plus VSCR and VRSave, 32 values
  432.                                   of 128 bits each, one value of 128 bits, and one 32 bit value.
  433.           MachineInformation    -> The CTR, LR, PC, each of 64 bits.  The CR, XER, MSR, MQ,
  434.                                   exception kind, and DSISR, each of 32 bits.  The 64 bit DAR.
  435.           ExceptionInfo        -> Only memory exceptions are specified, 4 fields of 32 bits each.
  436.                                   Note that this type only covers memory exceptions on 32-bit CPUs!
  437. }
  438.  
  439.  
  440.  
  441. CONST
  442.                                                                 {  Values for the TaskStateKind to MPExtractTaskState and MPSetTaskState. }
  443.     kMPTaskStateRegisters        = 0;                            {  The task general registers. }
  444.     kMPTaskStateFPU                = 1;                            {  The task floating point registers }
  445.     kMPTaskStateVectors            = 2;                            {  The task vector registers }
  446.     kMPTaskStateMachine            = 3;                            {  The task machine registers }
  447.     kMPTaskState32BitMemoryException = 4;                        {  The task memory exception information for 32-bit CPUs. }
  448.  
  449.                                                                 {  Option bits and numbers for MPDisposeTaskException. }
  450.     kMPTaskPropagate            = 0;                            {  The exception is propagated. }
  451.     kMPTaskResumeStep            = 1;                            {  The task is resumed and single step is enabled. }
  452.     kMPTaskResumeBranch            = 2;                            {  The task is resumed and branch stepping is enabled. }
  453.     kMPTaskResumeMask            = $0000;                        {  The task is resumed. }
  454.     kMPTaskPropagateMask        = $01;                            {  The exception is propagated. }
  455.     kMPTaskResumeStepMask        = $02;                            {  The task is resumed and single step is enabled. }
  456.     kMPTaskResumeBranchMask        = $04;                            {  The task is resumed and branch stepping is enabled. }
  457.  
  458.  
  459. {  ------------------------------------------------------------------------------------------- }
  460.  
  461. FUNCTION MPSetExceptionHandler(task: MPTaskID; exceptionQ: MPQueueID): OSStatus; C;
  462. FUNCTION MPThrowException(task: MPTaskID; kind: MPExceptionKind): OSStatus; C;
  463. FUNCTION MPDisposeTaskException(task: MPTaskID; action: OptionBits): OSStatus; C;
  464. FUNCTION MPExtractTaskState(task: MPTaskID; kind: MPTaskStateKind; info: UNIV Ptr): OSStatus; C;
  465. FUNCTION MPSetTaskState(task: MPTaskID; kind: MPTaskStateKind; info: UNIV Ptr): OSStatus; C;
  466. {  ------------------------------------------------------------------------------------------- }
  467.  
  468. FUNCTION MPRegisterDebugger(queue: MPQueueID; level: MPDebuggerLevel): OSStatus; C;
  469. FUNCTION MPUnregisterDebugger(queue: MPQueueID): OSStatus; C;
  470.  
  471.  
  472.  
  473. {
  474.    §
  475.    ===========================================================================================
  476.    Remote Call Services
  477.    ====================
  478. }
  479.  
  480.  
  481.  
  482. TYPE
  483. {$IFC TYPED_FUNCTION_POINTERS}
  484.     MPRemoteProcedure = FUNCTION(parameter: UNIV Ptr): Ptr; C;
  485. {$ELSEC}
  486.     MPRemoteProcedure = ProcPtr;
  487. {$ENDC}
  488.  
  489.     MPRemoteContext                        = UInt8;
  490.  
  491. CONST
  492.     kMPAnyRemoteContext            = 0;
  493.     kMPOwningProcessRemoteContext = 1;
  494.  
  495.  
  496. FUNCTION MPRemoteCall(remoteProc: MPRemoteProcedure; parameter: UNIV Ptr; context: ByteParameter): Ptr; C;
  497. {  ! MPRemoteCall is new in version 2.0. }
  498. {
  499.    §
  500.    ===========================================================================================
  501.    Checking API Availability
  502.    =========================
  503. }
  504.  
  505.  
  506. {
  507.    ===========================================================================================
  508.    *** WARNING: You must properly check the availability of MP services before calling them!
  509.    ===========================================================================================
  510.    
  511.    Checking for the availability of the MP API is rather ugly.  This is a historical problem,
  512.    caused by the original implementation letting itself get prepared when it really wasn't
  513.    usable and complicated by some important clients then depending on weak linking to "work".
  514.    (And further complicated by CFM not supporting "deferred" imports, which is how many
  515.    programmers think weak imports work.)
  516.    
  517.    The end result is that the MP API library may get prepared by CFM but be totally unusable.
  518.    This means that if you import from the MP API library, you cannot simply check for a
  519.    resolved import to decide if MP services are available.  Worse, if you explicitly prepare
  520.    the MP API library you cannot assume that a noErr result from GetSharedLibrary means that
  521.    MP services are available.
  522.    
  523.    • If you import from the MP API library you MUST:
  524.    
  525.           Use the MPLibraryIsLoaded macro (or equivalent code in languages other than C) to tell
  526.           if the MP API services are available.  It is not sufficient to simply check that an
  527.           imported symbol is resolved as is commonly done for other libraries.  The macro expands
  528.           to the expression:
  529.    
  530.               ( ( (UInt32)_MPIsFullyInitialized != (UInt32)kUnresolvedCFragSymbolAddress ) &&
  531.                 ( _MPIsFullyInitialized () ) )
  532.    
  533.           This checks if the imported symbol _MPIsFullyInitialized is resolved and if resolved
  534.           calls it.  Both parts must succeed for the MP API services to be available.
  535.    
  536.    • If you explicitly prepare the MP API library you MUST:
  537.    
  538.           Use code similar to the following example to tell if the MP API services are available.
  539.           It is not sufficient to depend on just a noErr result from GetSharedLibrary.
  540.    
  541.               OSErr                        err;
  542.               Boolean                        mpIsAvailable            = false;
  543.               CFragConnectionID            connID                    = kInvalidID;
  544.               MPIsFullyInitializedProc    mpIsFullyInitialized    = NULL;
  545.    
  546.               err    = GetSharedLibrary    ( "\pMPLibrary", kCompiledCFragArch, kReferenceCFrag,
  547.                                         &connID, NULL, NULL );
  548.    
  549.               if ( err == noErr ) (
  550.                   err    = FindSymbol    ( connID, "\p_MPIsFullyInitialized",
  551.                                         (Ptr *) &mpIsFullyInitialized, NULL );
  552.               )
  553.    
  554.               if ( err == noErr ) (
  555.                   mpIsAvailable = (* mpIsFullyInitialized) ();
  556.               )
  557.    
  558.    ===========================================================================================
  559. }
  560.  
  561.  
  562. FUNCTION _MPIsFullyInitialized: BOOLEAN; C;
  563.  
  564. TYPE
  565. {$IFC TYPED_FUNCTION_POINTERS}
  566.     MPIsFullyInitializedProc = FUNCTION: BOOLEAN; C;
  567. {$ELSEC}
  568.     MPIsFullyInitializedProc = ProcPtr;
  569. {$ENDC}
  570.  
  571. {
  572.    ===========================================================================================
  573.    The MPLibraryIsLoaded service is a macro under C that expands to the logical expression:
  574.           ( (UInt32)MPProcessors != (UInt32)kUnresolvedCFragSymbolAddress )
  575.    The intention is to check if the imported symbol MPProcessors is resolved.  For other
  576.    languages use the equivalent expression.
  577.    ===========================================================================================
  578. }
  579. {
  580.    §
  581.    ===========================================================================================
  582.    Miscellaneous Services
  583.    ======================
  584. }
  585.  
  586.  
  587. PROCEDURE _MPLibraryVersion(VAR versionCString: ConstCStringPtr; VAR major: UInt32; VAR minor: UInt32; VAR release: UInt32; VAR revision: UInt32); C;
  588. {
  589.    §
  590.    ===========================================================================================
  591.    Unofficial Services
  592.    ===================
  593. }
  594.  
  595.  
  596. {
  597.    ===========================================================================================
  598.    *** WARNING ***
  599.    These services are not part of the officially documented multiprocessing API.  They may not
  600.    be avaliable in future versions of Mac OS multiprocessing support, or in environments that
  601.    have a different underlying OS architecture such as Mac OS on top of a microkernel, the
  602.    Mac OS Blue Box under Mac OS X, native MP support in Mac OS X, etc.
  603.    ===========================================================================================
  604. }
  605.  
  606.  
  607. FUNCTION _MPAllocateSys(size: ByteCount): LogicalAddress; C;
  608. {  Use MPAllocateAligned instead. }
  609. FUNCTION _MPRPC(remoteProc: MPRemoteProcedure; parameter: UNIV Ptr): Ptr; C;
  610. {  Use _MPRemoteCall instead. }
  611. FUNCTION _MPTaskIsToolboxSafe(task: MPTaskID): BOOLEAN; C;
  612. FUNCTION _MPLibraryIsCompatible(versionCString: ConstCStringPtr; major: UInt32; minor: UInt32; release: UInt32; revision: UInt32): BOOLEAN; C;
  613.  
  614.  
  615. {
  616.    §
  617.    ===========================================================================================
  618.    Defunct Services
  619.    ================
  620. }
  621.  
  622.  
  623. {$IFC UNDEFINED MPIncludeDefunctServices }
  624. {$SETC MPIncludeDefunctServices := 0 }
  625. {$ENDC}
  626.  
  627. {$IFC MPIncludeDefunctServices }
  628. PROCEDURE _MPDebugStr(msg: Str255); C;
  629. FUNCTION _MPStatusPString(status: OSStatus): StringPtr; C;
  630. FUNCTION _MPStatusCString(status: OSStatus): ConstCStringPtr; C;
  631.  
  632. {$ENDC}  {MPIncludeDefunctServices}
  633.  
  634. {  =========================================================================================== }
  635.  
  636.  
  637.  
  638. {$ALIGN RESET}
  639. {$POP}
  640.  
  641. {$SETC UsingIncludes := MultiprocessingIncludes}
  642.  
  643. {$ENDC} {__MULTIPROCESSING__}
  644.  
  645. {$IFC NOT UsingIncludes}
  646.  END.
  647. {$ENDC}
  648.